﻿using System.Text;

namespace _2_字符串
{
    internal class Program
    {
        static void Main(string[] args)
        {
            #region 1_初始化字符串

            //char[] cdb = { 'a', 'b', 'c', 'd', 'e' };

            //string lang = "C#";
            //String ide= "Visual Studio";
            //string db = new string(cdb); // 可以使用字符数组初始化字符串

            //Console.WriteLine(lang);
            //Console.WriteLine(ide);
            //Console.WriteLine(db);

            //StringBuilder sb = new StringBuilder(lang);
            //StringBuilder sb2 = new StringBuilder();

            //sb2.Append("Fields");
            //sb2.Append("of");
            //sb2.Append("Life");

            //Console.WriteLine(sb2);
            //Console.WriteLine(sb);

            #endregion

            #region 2_字符串插值

            //string name = "Jerry";
            //int age = 20;
            //string address = "China";

            //Console.WriteLine($"{name} is {age} years old. He lives in {address}.");
            //DateTime now = DateTime.Now;
            //Console.WriteLine($"{now:yyyy-MM-dd HH:mm:ss}"); // 日期的格式化输出

            DateTime now = DateTime.Now;
            Console.WriteLine($"现在时间为{now:yyyy-MM-dd HH:mm:ss}");

            #endregion

            #region 3_常规字符串

            //string s1 = "deep \t forest";
            //string s2 = "deep \n forest";
            //// 普通字符串
            //Console.WriteLine(s1);
            //Console.WriteLine(s2);

            //// \\t 就是 \t
            //string path = "C:\\Users\\Admin\\Documents\\test";
            //Console.WriteLine(path);

            //// 简便的去转义逐字字符串@: 告诉编译器，这个字符串不需要转义
            //string s3 = @"C:\Users\Admin\Documents\test";
            //Console.WriteLine(s3);

            #endregion

            #region 4_字符串是对象

            //string lang = "C#";
            //string langName = lang.GetType().Name; // 获取类型名, String为对象的类型名
            //Console.WriteLine(langName);
            //Console.WriteLine(lang.GetType().BaseType);

            //// 判断字符串是否为空
            //if(lang.Equals(String.Empty))
            //{
            //    Console.WriteLine("空字符串");
            //}
            //else
            //{
            //    Console.WriteLine("非空字符串");
            //}
            //int len = lang.Length; // Java中的话使用的是也是length属性
            //Console.WriteLine(len); // 字符串的长度

            #endregion

            #region 5_可变&不可变字符串

            //// String为不可变字符序列, 而StringBuilder为可变字符序列, 同Java中的StringBuilder
            //string name = "Jane";
            //string name2 = name.Replace('J', 'K'); // String的方法都不会改变原字符串, 而是会返回一个新的字符串
            //Console.WriteLine(name2);
            //StringBuilder sb = new StringBuilder("Jane");
            //Console.WriteLine(sb);
            //// 新字符替换给定索引处的字符
            //sb[0] = 'K';
            //sb.Replace('J', 'K', 0, 1); // StringBuilder的方法会改变原字符串
            //sb.Replace('n', 't', 2, 1);
            //Console.WriteLine(sb);

            #endregion

            #region 6_字符串拼接

            //string name3 = "Jane" + " " + "Doe";
            //Console.WriteLine(name3);

            #endregion

            #region 7_使用引号

            //Console.WriteLine("There are many stars.");
            //Console.WriteLine("He said, \"Which one is your favourite?\"");

            // 使用@的话, 会按照引号中的内容来解析
            Console.WriteLine(@"
            Lao Tzu has said: 
            ""If you do not change direction, you may end up 
            where you are heading.""
            ");

            #endregion

            #region 8_比较字符串, 使用的都是Unicode字符集

            String name = "12";
            String AnotherName = "12";
            //// 与Java不同的是, C#中的字符串可以使用==比较, 而Java中只能使用equals()比较
            //Console.WriteLine(name == AnotherName);  // True
            // C#中没有equals方法, 但是有一个比较方法, 那就是string对象的Compare方法或者String对象的CompareOrdinal方法, 但是这两个方法的使用场景有所不同, 下个知识点将会介绍
            Console.WriteLine(String.CompareOrdinal(name, AnotherName));

            //string str1 = "Hello";
            //string str2 = "hello";
            //Console.WriteLine(str1 == str2); // False
            //// 第三个参数ignoreCase: 是否忽略大小写
            //Console.WriteLine(string.Compare(str1, str2, true)); // 0, 忽略大小写比较
            //Console.WriteLine(string.Compare(str1, str2, false)); // 1, 不忽略大小写比较

            #endregion

            #region 8.5 string.Compare和String.CompareOrdinal的区别

            #region string.Compare
            
            // 该方法允许你指定文化信息（CultureInfo）和比较选项（CompareOptions），从而根据不同的语言环境和需求进行比较, 比如考虑大小写、重音符号、语言特有的排序规则等
            // 使用场景: 
            // 1> 需要根据特定的文化或区域设置来比较字符串时，比如考虑大小写、重音符号、语言特有的排序规则
            // 2> 需要进行不区分大小写的比较时，可以指定 StringComparison.InvariantCulture 或 StringComparison.CurrentCultureIgnoreCase 等参数
            // 3> 需要根据特定的排序规则（如电话簿排序）进行比较时
            string str1 = "café";
            string str2 = "cafe";
            
            #endregion

            #endregion

            #region 9_字符串元素

            //// 不可变字符串: String 类
            //char[] crs = { 'Z', 'e', 't', 'C', 'o', 'd', 'e' };
            //String s = new String(crs);

            //char c1 = s[0];
            //char c2 = s[(s.Length - 1)];

            //Console.WriteLine(c1);
            //Console.WriteLine(c2);

            //int i1 = s.IndexOf('e');
            //int i2 = s.LastIndexOf('e');

            //Console.WriteLine("The first index of character e is " + i1);
            //Console.WriteLine("The last index of character e is " + i2);

            //Console.WriteLine(s.Contains("t"));
            //Console.WriteLine(s.Contains("f"));

            //char[] elements = s.ToCharArray();

            //foreach (char el in elements)
            //{
            //    Console.WriteLine(el);
            //}

            //// 可变的字符串: StringBuilder
            //StringBuilder sb = new StringBuilder("Misty mountains");
            //Console.WriteLine(sb);

            //sb.Remove(sb.Length - 1, 1);
            //Console.WriteLine(sb);

            //sb.Append('s');
            //Console.WriteLine(sb);

            //sb.Insert(0, 'T');
            //sb.Insert(1, 'h');
            //sb.Insert(2, 'e');
            //sb.Insert(3, ' ');
            //Console.WriteLine(sb);

            //sb.Replace('M', 'm', 4, 1);
            //Console.WriteLine(sb);

            #endregion

            #region 10_字符串连接和拆分Join和Split

            //var items = new string[] { "C#", "Java", "Python", "C++" };
            //var langs  = string.Join(",", items);
            //Console.WriteLine(langs);
            //string[] lang2 = langs.Split(',');
            //foreach (var item in lang2)
            //{
            //    Console.WriteLine(item);
            //}

            #endregion

            #region 11_常见方法

            //string word = "Determination";
            //Console.WriteLine(word.Length);
            //Console.WriteLine(word.ToUpper());
            //Console.WriteLine(word.ToLower());
            //Console.WriteLine(word.IndexOf("e"));
            //Console.WriteLine(word.IndexOf("e", 4));
            //Console.WriteLine(word.IndexOf("e", 4, 1));
            //Console.WriteLine(word.Substring(4));
            //Console.WriteLine(word.Substring(4, 4));
            //Console.WriteLine(word.Replace("e", "a"));

            #endregion

            #region 12_字符串复制与克隆Copy()和Clone()

            //string str = "ZetCode";
            //// 返回的是该字符串的引用副本, 不是堆上字符串的独立副本, 共享引用
            //string cloned = (string) str.Clone();
            //// 返回的是一个新的字符串实例, 该实例的值与原字符串相同, 是堆上字符串的独立副本
            //string copied = string.Copy(str);
            //Console.WriteLine(cloned);
            //Console.WriteLine(copied);

            // // ReferenceEquals()方法可以用来比较两个参考对象是否是同一个对象
            //Console.WriteLine(ReferenceEquals(str, cloned)); //True
            //Console.WriteLine(ReferenceEquals(str, copied)); //False

            #endregion

            #region 13_格式化字符串

            // {index, length:D} : index表示第一个参数(从0开始)，length表示第二个参数(显示的长度, 不够用空字符串填充)，D表示十进制
            // D: 十进制 X: 十六进制
            //Console.WriteLine("{0}  {1, 12}", "Decimal", "Hexadecimal");

            //Console.WriteLine("{0:D}  {1,8:X}", 502, 546);
            //Console.WriteLine("{0:D}  {1,8:X}", 345, 765);
            //Console.WriteLine("{0:D}  {1,8:X}", 320, 654);
            //Console.WriteLine("{0:D}  {1,8:X}", 120, 834);
            //Console.WriteLine("{0:D}  {1,8:X}", 620, 454);

            //// T: Time M:月 Y:日
            //DateTime today = DateTime.Now;

            //Console.WriteLine(string.Format("Short date: {0:d}", today));
            //Console.WriteLine(string.Format("Long date: {0:D}", today));
            //Console.WriteLine(string.Format("Short time: {0:t}", today));
            //Console.WriteLine(string.Format("Long time: {0:T}", today));
            //Console.WriteLine(string.Format("Month: {0:M}", today));
            //Console.WriteLine(string.Format("Year: {0:Y}", today));

            #endregion
        }
    }
}